home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
51329
/
51329.xpi
/
chrome
/
firefound.jar
/
content
/
geolocation.js
< prev
next >
Wrap
Text File
|
2009-12-14
|
5KB
|
195 lines
/**
* Geolocation object to fill in for Firefox's broken geolocation support
* for extensions.
*
* Contacts Google's geolocation service, which uses a list of WiFi access
* points and IP address to geolocate.
*
* @author chris
*/
var GEOLOCATION = {
ERROR_WIFI_NOT_AVAILABLE : -2147221231,
/**
* The cached last position.
*/
_lastPosition : null,
/**
* Making the last position readonly from outside of the object.
*/
get lastPosition() { return this._lastPosition; },
set lastPosition() { throw Exception; },
/**
* @var hash
* A list of callbacks that have registered with the geolocation service
* to get notifications of new locations.
*/
listeners : {},
/**
* Service initializer. Uses Firefox 3.5's wifi monitoring to determine change in location.
*/
load : function () {
var wifi_service = Components.classes["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor);
wifi_service.startWatching(this);
},
/**
* Service unloader. Cleans up after the initializer.
*/
unload : function () {
var wifi_service = Components.classes["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor);
wifi_service.stopWatching(this);
},
/**
* The callback function for the wifi listener.
*
* @param array accessPoints A list of WiFi access ponts.
*/
onChange : function (accessPoints) {
// Contact the Geolocation service and get the new coordinates.
var _length = accessPoints.length;
// The JSON request for the geolocation service.
var request_body = {
version: "1.1.0",
host: "firefound.com",
request_address: true
};
request_body.wifi_towers = [];
if (_length > 0) {
for (var i = 0; i < _length; i++) {
// Include each wifi access point and its strength.
request_body.wifi_towers.push(
{
"mac_address" : accessPoints[i].mac,
"signal_strength": accessPoints[i].signal,
"age": 0,
"ssid": accessPoints[i].ssid
}
);
}
}
// Ask Google for the geophysical location.
var req = new XMLHttpRequest();
req.open("POST", "http://www.google.com/loc/json", true);
var self = this;
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (FIREFOUND.prefs.getBoolPref("debug")) {
FIREFOUND.log("onChange: " + req.responseText);
}
var json = JSON.parse(req.responseText);
if ("location" in json) {
// Save this location for easy, painless access.
self._lastPosition = json.location;
self._lastPosition.wifi_towers = request_body.wifi_towers;
for (listener in self.listeners) {
// Notify all the listeners of a new location.
self.listeners[listener].success(self._lastPosition);
}
}
else {
self.log("No location could be determined.");
}
}
};
req.send(JSON.stringify(request_body));
},
/**
* Error callback for the WiFi listener. Not a big deal (unless it errors over and over).
*/
onError : function (value) {
if (value == GEOLOCATION.ERROR_WIFI_NOT_AVAILABLE) {
// User does not have WiFi interface.
// Just use the IP address.
this.onChange([]);
}
else {
this.log("WiFi Listener Error: " + value);
}
},
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIWifiListener) ||
iid.equals(Components.interfaces.nsISupports)) {
return this;
}
throw Components.results.NS_ERROR_NO_INTERFACE;
},
/**
* Public interface to the geolocation service.
*
* @param function The success callback.
* @param function The error callback.
* @param options Unused.
*/
getCurrentPosition : function (successCallback, errorCallback, options) {
if (this.lastPosition) {
successCallback(this.lastPosition);
}
else {
// An unlikely scenario, since the WIFI onchange will be called as soon as the service starts.
// TODO Fetch the current access points and get the location.
errorCallback("lastPosition is undefined");
}
},
/**
* Allows objects to register for notifications of position changes.
*
* @param function The success callback.
* @param function The error callback.
* @param options Unused.
*/
watchPosition : function (successCallback, errorCallback, options) {
// Use the current microtime as the id of the watcher.
var watchId = new Date().getTime();
this.listeners[watchId] = { success: successCallback, errors: errorCallback };
return watchId;
},
/**
* Removes a listener from the position change notification list.
*
* @param string The id of the listener.
*/
clearWatch : function (watchId) {
if (watchId in this.listeners) {
delete this.listeners[watchId];
}
},
/**
* Log a message to the Error Console.
*
* @param string message
*/
log : function (message) {
var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
consoleService.logStringMessage("GEOLOCATION: " + message);
}
};
// Automatically load this service when it's included.
addEventListener("load", function () { GEOLOCATION.load(); }, false);
addEventListener("unload", function () { GEOLOCATION.unload(); }, false);